#include "I2CSlave.h"
#include "log.h"

I2CSlave::I2CSlave(Mail<>& mb):_mb(mb)
{
    _receive_updated = false; 
    _updated         = false;
    _reg_read_address = 0;

}
I2CSlave::~I2CSlave()
{

}
void I2CSlave::begin()
{
    Wire.begin(_address);
}
void I2CSlave::begin(int address)
{
    Wire.end();
    _address = address;
    Wire.begin(_address);
}
void I2CSlave::frequency (uint32_t hz)
{
    Wire.setClock(hz);
}
void I2CSlave::on_receive(receive_callback cb)
{
    Wire.onReceive(cb);
}
void I2CSlave::on_request(request_callback cb)
{
    Wire.onRequest(cb);
}

// uint8_t I2CSlave::parse_master_read_request()
// {
//     this->read(_reg_address.data,2);
//     _cb.reset();
//     return _reg_address.value;
// }

int I2CSlave::write(const uint8_t* data, int length)
{
    return Wire.write(data,length);
}
int I2CSlave::write(int data)
{
    return Wire.write(data);
}

void I2CSlave::end()
{
    Wire.endTransmission();
}

bool I2CSlave::read(os::memory_pool_t::memory_node_t& data)
{
    if(_mb.empty()){
        return false;
    }

    os::memory_pool_t::memory_node_t* node;
    if(_mb.get(node)){
      memcpy(data.memory.data, node->memory.data,node->memory.size);
      data.memory.size = node->memory.size;
      _mb.free(node);
      return true;
    }else{
      data.memory.size = 0;
    }
   
    return false;
}

uint8_t I2CSlave::get_reg_read_address()
{
    return _reg_read_address;
}

void I2CSlave::handle_on_receive(int howMany)
{
    uint8_t c = Wire.read();

    switch(c){
      case 0xFF://主机写了一条读命令
      {
          howMany--;
          if(0 < Wire.available()) { 
            _reg_read_address = Wire.read(); 
            howMany--;
          }
          while(howMany>0 && (Wire.available()>0)){
             howMany--;
            c = Wire.read();
          }
      }
      break;
      case 0x00://主机写了一条写命令
      {
        auto mem = _mb.alloc();
        if(!mem){
          if(!_mb.get(mem)){
            log::debug("i2c mem null\r\n");
            break;
          }
        }
        mem->memory.size = howMany-1;
     
        for(size_t i=0;i<mem->memory.size;i++){ 
            mem->memory.data[i] =  Wire.read();
        }
        _mb.put(mem);
      }
      break;
      default:
      break;
    }

}